Skip to main content

API Description

The Basics

The API is primarily composed by the following elements:

  • Objects: Each object is a node in the graph. Objects are of one of the following types:

    • Entity
    • Image
    • Video
    • Blob
    • DescriptorSet
    • Descriptor
    • BoundingBox
    • Polygon
    • Frame
  • Connections: express relationship between objects.

  • Commands: perform specific actions on objects (Add/Find/Update/Delete) and the database (GetStatus/GetSchema).

Queries

ApertureDB expects queries over one of its connectors.

A query is composed of:

  • a string representing a JSON array of one or more commands, and
  • [optional] an "array of blobs".

The array of blobs is used to send and receive binary data. Each element of the array can contain one of the following elements:

  • An encoded Image (either a complete image, or a frame of a video)
  • An encoded Video
  • A feature vector (which is in itself an array of floating point values)
  • A user-defined blob

A query is received by ApertureDB, processed, and a response is returned. A response is composed in the same manner as a query:

  • a string representing a JSON array with the same number of elements as the query, and
  • [optional] an "array of blobs", if blobs are returned.

A query is processed transactionally in ApertureDB: either all the commands are correctly executed, or none of them are executed and an error status is returned.

Here is an example of a query and its corresponding response, using the Python connector:

from aperturedb import Connector

db = Connector.Connector("mydatabase.mydomain.com",
user="admin", password="admin")

query = [{
"AddEntity": {
"class": "Person",
"properties": {
"name": "Luis",
"email": "luis@aperturedata.io",
"id": 30
}
}
},{
"AddImage": {
"properties": {
"description": "profile photo",
"year_captured": 1990
}
}
}]

# Because we are inserting an image, a blob is expected
# in the blob_array

fd = open("luis_profile_photo.jpg", "rb")
image = fd.read()

blobs_array = [image]

# Execute the transaction
response, blobs = db.query(query, blobs_array)

# response is a dictionary, we use a helper function to
# print the JSON array nicely.
print(db.get_last_response_str())
print(f"Blobs returned: {len(blobs)}")

Output:

[{
"AddEntity": {
"status": 0
}
}, {
"AddImage": {
"status": 0
}
}]

In this example, no blob is returned as a result of the query, and the "blobs" variable will be an empty array.

Here is another example where the opposite happens: no blob is sent as part of the query, but blobs are returned as part of the response:

from aperturedb import Connector

db = Connector.Connector("mydatabase.mydomain.com")

query = [{
"FindImage": {
"constraints": {
"year_captured": ["==", 1990]
},
"results": {
"list": ["year_captured", "description"]
}
}
}]

# Execute the transaction
response, blobs = db.query(query)

# response is a dictionary, we use a helper function to
# print the JSON array nicely.
print(db.get_last_response_str())

# Check the number of returned images:
print(f"Number of returned images: {len(blobs)}")

Output:

[{
"FindImage": {
"status": 0,
"blobs_start": 0,
"entities": [{
"_blob_index": 0,
"year_captured": 1990,
"description": "profile photo"
}],
"returned": 1
}
}]

In this case, the array of blobs ("blobs" variable) will have 1 elements, each of which is an encoded image.

Once the data usage and data collection/preprocessing requirements of an application are understood, it is time to connect the application to ApertureDB server because ApertureDB offers the unique capabilities of storing metadata in a structured graph database as well as takes care of dealing with the actual data through one unified API, described in this documentation. We provide C++ and Python client libraries for applications to communicate with ApertureDB.

Using the API

We define a set of JSON-based API calls that allow an application to interact with ApertureDB and exploit its strengths. A user application will use the ApertureDB API by defining metadata as shown in examples above and throughout this documentation, and passing along blobs. The client side ApertureDB library provides a simple query function that accepts a JSON string with commands and an array or vector of blobs. Internally, the library wraps the query string and blob in a protobuf and sends it to ApertureDB. It also receives a similarly wrapped response from ApertureDB and returns it to the client. The responses will require JSON parsing on the client side, starting with the metadata string that will indicate how to interpret blobs.